package org.swfer.UIC 
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	
	/**
	 * 列表.只提供数据单选
	 * 必须部件 scrollBar, item0,item1,item2~~
	 * 回调事件 select
	 * @author swfer
	 */
	public class List extends Component
	{
		public static const SELECT:String = 'select';
		
		protected var renderItems:Array;
		protected var virtualDatas:Array;
		protected var cacheVirtualData:VirtualData
		protected var _array:Array;
		protected var _scrollBar:ScrollBar;
		protected var _selectedDataItem:Object;
		protected var _selectedRenderItem:*;
		protected var _selectedIndex:int = -1;
		protected var renderItemDef:Class;
		protected var itemHeight:int;
		private var dataOffset:int = 0;
		
		
		public function List(view:MovieClip,renderItemDef:Class=null)
		{
			super(view);
			this.renderItemDef = renderItemDef;
		}
		
		/////////////////////////////////////
		//methods
		/////////////////////////////////////
		
		override public function dispose():void
		{
			if (disposed) return;
			
			super.dispose();
			_scrollBar.dispose();
			
			_array = null;
			_selectedDataItem = null;
			_selectedRenderItem = null;
			
			virtualDatas = null;
			cacheVirtualData = null;
		}
		
		override protected function init():void
		{
			var h:int;
			renderItems = [];
			for (var i:int = 0; i < int.MAX_VALUE; i++) 
			{
				var item:DisplayObject = view.getChildByName('item' + i);
				if (item == null) break;
				renderItems.push(new (renderItemDef || ListRenderItem)(item as MovieClip));
				itemHeight = item.height;
			}
			
			_scrollBar = new ScrollBar(view.getChildByName('scrollBar') as MovieClip);
			_scrollBar.addCallBack(ScrollBar.CHANGE, onScrollChange);
		}
		
		override protected function addEvt():void
		{
			for each (var item:Component in renderItems) 
			{
				item.view.addEventListener(MouseEvent.CLICK,onItemViewClick);
			}
		}
		
		override protected function removeEvt():void
		{
			for each (var item:Component in renderItems) 
			{
				item.view.removeEventListener(MouseEvent.CLICK,onItemViewClick);
			}
		}
		
		/**
		 * 滚动条改变时翻页数据
		 * @param	target
		 */
		protected function onScrollChange(target:ScrollBar):void
		{
			if (!virtualDatas || virtualDatas.length == 0) return;
			
			var pre:int = Math.round(target.value * (virtualDatas.length-renderItems.length));
			if (pre == dataOffset) return;
			
			dataOffset = pre;
			flipOverData();
		}
		
		/**
		 * 数据翻页。
		 */
		protected function flipOverData():void
		{
			var dataLen:int = virtualDatas.length;
			var itemLen:int = renderItems.length;
			
			for (var i:int = 0; i < itemLen; i++) 
			{
				var render:IRenderItem=renderItems[i] as IRenderItem
				
				if (dataOffset+i < dataLen)
				{
					var virtualData:VirtualData = virtualDatas[dataOffset + i];
					render.data = virtualData.data;
					
					render.selected = virtualData.selected;
					render.view.visible = true;
				}
				else
				{
					render.data = null;
					render.view.visible = false;
				}
			}
		}
		
		/**
		 * 初始化数据。数据刷新偏移复位。初始化虚拟数据。重置滚动条
		 */
		private function initData():void
		{
			dataOffset = 0;
			virtualDatas = [];
			_selectedIndex = -1;
			
			var i:int = 0;
			for each (var item:Object in _array) 
			{
				virtualDatas.push(new VirtualData(i, item, false));
				i++
			}
			
			var vn:int = virtualDatas.length;
			var rn:int = renderItems.length;
			var p:Number = (rn/(vn - rn))/rn;
			
			_scrollBar.reset(vn * itemHeight, rn * itemHeight);
			_scrollBar.interval = _scrollBar.dragRectHeight * p;
			
			flipOverData();
		}
		
		/////////////////////////////////////
		// evt handlers
		/////////////////////////////////////
		
		/**
		 * 渲染单元点击。
		 */
		private function onItemViewClick(e:MouseEvent):void 
		{
			var tag:String = e.currentTarget.name;
			var re:RegExp =/[0-9]/g;
			var index:int = int(tag.match(re).join(''));
			
			
			for (var i:int = 0; i < renderItems.length; i++) 
			{
				var render:IRenderItem = renderItems[i] as IRenderItem;
				
				if (i == index)
				{
					var virtualData:VirtualData = virtualDatas[i+dataOffset] as VirtualData;
					virtualData.selected = true;
					
					if (cacheVirtualData) cacheVirtualData.selected = false;
					cacheVirtualData = virtualData;
					
					_selectedDataItem = virtualData.data;
					_selectedRenderItem = render;
					
					if (render.selected == false) executeCallBack(SELECT);
					render.selected = true;
					
					_selectedIndex = i;
				}
				else
				{
					render.selected = false;
				}
			}
		}
		
		/////////////////////////////////////
		//getters/setters
		/////////////////////////////////////
		
		/** 源数据 **/
		public function get array():Array {return _array;}
		public function set array(value:Array):void 
		{
			_array = value;
			initData();
		}
		
		/** 选中渲染器 **/
		public function get selectedRenderItem():* { return _selectedRenderItem; }
		
		/** 选中索引 **/
		public function get selectedIndex():int { return _selectedIndex;}
		
		/** 选中数据项 **/
		public function get selectedDataItem():Object { return _selectedDataItem; }
		
		/** 列表渲染单元数据注入规则 **/
		public function get renderItemInjectMethod():Function
		{
			for each (var item:Component in renderItems) 
			{
				return item.injectMethod;
			}
			
			return null;
		}
		public function set renderItemInjectMethod(value:Function):void
		{
			for each (var item:Component in renderItems) 
			{
				item.injectMethod=value;
			}
		}
		
		/** 滚动条控件 **/
		public function get scrollBar():ScrollBar { return _scrollBar;}
		
		
		
	}

}